import { map, includes } from "lodash";
import React, {useEffect, useState} from "react";
import PropTypes from "prop-types";
import Select from "antd/lib/select";
import Input from "antd/lib/input";
import Form from "antd/lib/form";
import Button from "antd/lib/button";
import Divider from 'antd/lib/divider';
import { policy } from "@/services/policy";
import DataSource, { IMG_ROOT } from "@/services/data-source";
import { axios } from "@/services/axios";
import Widget from "@/services/widget";

const { TextArea } = Input;

export default function TemplateDrawer({ dashboardOptions, currentWidget }) {
  const [dataSources, setDataSources] = useState([]);
  const [changeKeys, setChangeKeys] = useState([]);
  const [isSaving, setIsSaving] = useState(false);
  const { EditTemplateWidget, refreshWidget } = dashboardOptions;
  
  useEffect(() => {
    DataSource.query().then(data => {
      setDataSources(data);
    });
  }, []);

  function onDataChange(key, isRemove=false) {
    if (isRemove) {
      if (includes(changeKeys, key)) {
        const keys = [...changeKeys];
        keys.splice(keys.indexOf(key),1);
        setChangeKeys(keys);
      } 
    } else if (!includes(changeKeys, key)) {
      const keys = [...changeKeys];
      keys.push(key);
      setChangeKeys(keys);
    } 
  }

  function onChange(key, paramValue) {
    const url = `api/widgets/${currentWidget.id}/template/${currentWidget.visualization.id}/${key}`;

    setIsSaving(true);
    axios.post(url, paramValue).then(w => {
      currentWidget = new Widget(w)
      EditTemplateWidget(currentWidget)
      refreshWidget(currentWidget);
      setIsSaving(false);
    });
  }
  
  const onFinish = (values) => {
    const key = Object.keys(values)[0];
    const paramValue = values[key];
    const url = `api/widgets/${currentWidget.id}/template/${currentWidget.visualization.id}/${key}`;

    if (!paramValue.datasource) delete paramValue.datasource
    if (!paramValue.data) delete paramValue.data

    setIsSaving(true);
    axios.post(url, paramValue).then(w => {
      currentWidget = new Widget(w)
      EditTemplateWidget(currentWidget)
      refreshWidget(currentWidget);
      setChangeKeys([]);
      setIsSaving(false);
    });
  };

  function getNode(key, param) {
    let node = null;

    switch (param.type) {
      case 'image':
        const logoFolder = currentWidget.template_logo.substr(0, currentWidget.template_logo.indexOf("."));
        const logoUrl = policy.getHost() + '/static/images/templates/' + logoFolder +'/';
        node = (
          <div>
            <span style={{display:'inline-block', fontWeight: 500}}>{param.title + '：'}</span>
            <div style={{display:'inline'}}>
              <Select
                mode="default"
                size="small"
                key={key + 'image' + currentWidget.id}
                defaultValue={param.value}
                onChange={value => onChange(key, {value: value})}
                disabled={isSaving}
                style={{ minWidth: 96 }}
              >
                {['0','1','2','3','4','5'].map(index => (  
                  <Select.Option key={index} value={index}>
                    <img src={logoUrl + index +'.png'} alt={param.title} width="96" height="48" />
                  </Select.Option>
                ))}
              </Select>
            </div>
          </div>
        );
        break;
      case 'enum':
        node = (
          <div>
            <span style={{display:'inline-block', fontWeight: 500}}>{param.title + '：'}</span>
            <div style={{display:'inline'}}>
              <Select
                mode="default"
                size="small"
                key={key + 'enum' + currentWidget.id}
                defaultValue={param.value}
                onChange={value => onChange(key, {value: value})}
                disabled={isSaving}
              >
                {param.values.split(';').map(keyvalue => (  
                  <Select.Option key={keyvalue.split(',')[0]} value={keyvalue.split(',')[0]}>
                    {keyvalue.split(',')[1]}
                  </Select.Option>
                ))}
              </Select>
            </div>
          </div>
        );
        break;
      case 'display':
      case 'data':
        node = (
          <div>
            <Divider style={{margin:'2px 0 2px 0', fontWeight: 500}}>{param.title}</Divider>
            {param.type === 'display' && (
            <div>
              <span style={{display:'inline-block', fontWeight: 500}}>颜色：</span>
              <Input size="small" type="color" style={{width:"60px"}} defaultValue={param.fontcolor || '#000000'}
                key={key + 'fontcolor' + currentWidget.id}
                onChange={e => onChange(key, { fontcolor: e.target.value })}
                disabled={isSaving}
              />
              &nbsp;&nbsp;
              <span style={{display:'inline-block', fontWeight: 500}}>字体：</span>
              <Input size="small" type="number" style={{width:"60px"}} defaultValue={param.fontsize || 15}
                key={key + 'fontsize' + currentWidget.id}
                onChange={e => onChange(key, { fontsize: e.target.value })}
                disabled={isSaving}
              />
            </div>
            )}
            <Form key={key + 'form' + currentWidget.id} size="small" layout="inline" onFinish={onFinish}>
            {!param.is_datasource && (<Form.Item name={[key, 'datasource']} label="数据源：" tooltip={param.placeholder && {title: (param.placeholder)}} style={{width: '100%'}}>
              <Select
                mode="default"
                size="small"
                key={key + 'datasource' + currentWidget.id}
                defaultValue={param.datasource}
                onSelect={(value)=> onDataChange(key + 'datasource', value===param.datasource)}
                disabled={isSaving}
              >
                (<Select.Option value="0">{!param.is_static ? "--静态信息--" : "--请选择--"}</Select.Option>)
                {!param.is_datasource && map(dataSources, ds => (
                  <Select.Option value={ds.id.toString()}>
                    <img src={`${IMG_ROOT}/${ds.type}.png`} width="20" alt={ds.type} />
                    {ds.name}
                  </Select.Option>  
                ))}
              </Select>
            </Form.Item>
            )}
            <Form.Item name={[key, 'data']} style={{width: '100%'}}>
              <TextArea
                key={key + 'data' + currentWidget.id}
                rows={4}
                defaultValue={param.data}
                onChange={(e)=> onDataChange(key +'data', e.target.value===param.data)}
                disabled={isSaving}
              />
            </Form.Item>
            <Form.Item>
              <Button htmlType="submit" 
                disabled={isSaving || (!includes(changeKeys, key + 'datasource') && !includes(changeKeys, key + 'data'))}
              >提交</Button>
            </Form.Item>
            </Form>
          </div>
        );
        break;
      default:
        node = null;
    }

    return node;
  }

  if (!currentWidget || !currentWidget.visualization || !currentWidget.visualization.template_parameters || !dataSources) {
    return null;
  }

  return (
    <React.Fragment>
    {map(Object.keys(currentWidget.visualization.template_parameters), key => getNode(key, currentWidget.visualization.template_parameters[key]))}
    </React.Fragment>
  );
}

TemplateDrawer.propTypes = {
  dashboardOptions: PropTypes.object.isRequired,    // eslint-disable-line react/forbid-prop-types
  currentWidget: PropTypes.object.isRequired,     // eslint-disable-line react/forbid-prop-types
};
